package pb

import (
	"chess_platform/controllers"
	. "chess_platform/internal/common"
	"chess_platform/internal/token"
	"encoding/json"
	"fmt"
)

type BaseUserInfo struct {
	Uid  int64  `json:"uid"`
	Name string `json:"name"`
}

type BaseController struct {
	controllers.BaseController
	BaseUserInfo
}

type GrantController struct {
	BaseController
}

func (b *BaseController) Prepare() {

	b.Res = new(controllers.Response)
	LogPB.Debug("用户输入:" + string(b.Ctx.Input.RequestBody))
	LogPB.Debug(fmt.Sprintf("用户访问(ID:%v)url:%v", b.Uid, b.Ctx.Input.URL()))
}

func (b *BaseController) Finish() {
	data, _ := json.Marshal(b.Data["json"])
	LogPB.Debug(fmt.Sprintf("用户(ID:%v)访问url:%v返回值:%v", b.Uid, b.Ctx.Input.URL(), string(data)))
}

func (b *GrantController) Prepare() {
	LogPB.Debug("用户输入:" + string(b.Ctx.Input.RequestBody))
	LogPB.Debug("用户访问url:" + b.Ctx.Input.URL())
	b.Res = new(controllers.Response)
	var (
		t        controllers.Token
		tokenStr string
		ex       *token.Export
	)

	err := b.Unmarshal(&t)
	if err != nil || t.Token == "" {
		tokenStr = b.Ctx.Input.Header("token")
		if tokenStr == "" {
			if tokenStr == "" {
				tokenStr = b.Ctx.Request.PostFormValue("token")
				if tokenStr == "" {
					b.ResponseFail("未带token访问")
					return
				}
			}
		}
	}
	if tokenStr != "" {
		ex, err = token.Parse(tokenStr)
	} else {
		tokenStr = t.Token
		ex, err = token.Parse(tokenStr)
	}

	if err != nil || ex.GetTokenType() != TokenPB {
		LogPB.Error(fmt.Sprintf("token解析错误:%v,或不是此Pc类型的token:%v,期望类型:%v", err, ex.GetTokenType(), TokenPB))
		b.Res.Code = ErrUserUnauthorized
		b.Res.Msg = MsgErrUserUnauthorized
		b.Response()
		return
	}

	b.Uid = ex.GetId()
	LogPB.Debug(fmt.Sprintf("用户访问(ID:%v)url:%v", b.Uid, b.Ctx.Input.URL()))

	//cache里不存在说明token已经过期了
	key := fmt.Sprintf("%v%v", KeyPbTokenCache, b.Uid)
	if ex.IsExpire() || !RedisCache.IsExist(key) {
		b.Res.Code = ErrUserUnauthorized
		b.Res.Msg = MsgErrUserExpire
		b.Response()
		return
	}

	//cache里的token与传进来的不一样的话表示此帐号在其它地方登录了
	tokenCache := RedisCache.GetString(key)
	if tokenCache != "" { // token存在缓存里
		if string(tokenCache) != tokenStr {
			b.Res.Code = ErrAlreadyLogin
			b.Res.Msg = MsgErrAlreadyLogin
			b.Response()
			return
		}
	} else { //token不存在缓存里
		b.Res.Code = ErrUserUnauthorized
		b.Res.Msg = MsgErrUserUnauthorized
		b.Response()
		return
	}

	keyAccessLimit := fmt.Sprintf("PbUserLimit-%v", b.Uid)
	if !AccessLimit(keyAccessLimit, Al.Frequency, Al.ExpireTime) {
		b.ResponseFail("操作过于频繁，请稍候再操作")
		return
	}
}
